package com.lion.common.spring.openapi;

import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerMethod;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Optional;

/**
 * 访问令牌帮助类
 * 检查是否需要包装响应体（按照优先级） AccessToken
 * 优先级：方法 > 类 > 接口方法 > 接口类
 * <p>
 * 这个帮助类似乎可以做成一个通用的帮助类，用于检查是否需要包装响应体（按照优先级）
 */
public class AccessTokenHelper {

    /**
     * 检查是否需要包装响应体（按照优先级） AccessToken
     * 优先级：方法 > 类 > 接口方法 > 接口类
     *
     * @param handlerMethod 处理方法
     * @return 是否需要包装响应体
     */
    public static boolean support(HandlerMethod handlerMethod) {
        // 检查类上面是否有@RestController
        if (AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), RestController.class) == null) {
            return false;
        }
        // 1. 检查方法上的注解
        AccessToken methodAnnotation = AnnotationUtils.findAnnotation(
                handlerMethod.getMethod(), AccessToken.class);
        if (methodAnnotation != null) {
            return methodAnnotation.required();
        }

        // 2. 检查类上的注解
        AccessToken classAnnotation = AnnotationUtils.findAnnotation(
                handlerMethod.getBeanType(), AccessToken.class);
        if (classAnnotation != null) {
            return classAnnotation.required();
        }

        // 3. 检查接口方法上的注解
        Optional<AccessToken> interfaceMethodAnnotation = findInterfaceAnnotation(
                handlerMethod.getMethod(), AccessToken.class);
        if (interfaceMethodAnnotation.isPresent()) {
            return interfaceMethodAnnotation.get().required();
        }

        // 4. 检查接口类上的注解
        for (Class<?> interfaceClass : handlerMethod.getBeanType().getInterfaces()) {
            AccessToken interfaceAnnotation =
                    AnnotationUtils.findAnnotation(interfaceClass, AccessToken.class);
            if (interfaceAnnotation != null) {
                return interfaceAnnotation.required();
            }
        }

        return false; // 默认不包装
    }
    /**
     * 查找接口方法上的注解
     *
     * @param method        方法
     * @param annotationType 注解类型
     * @param <A>            注解类型参数
     * @return 接口方法上的注解（如果存在）
     */
    private static <A extends Annotation> Optional<A> findInterfaceAnnotation(
            Method method, Class<A> annotationType) {
        for (Class<?> interfaceClass : method.getDeclaringClass().getInterfaces()) {
            try {
                Method interfaceMethod = interfaceClass.getMethod(
                        method.getName(), method.getParameterTypes());
                A annotation = AnnotationUtils.findAnnotation(interfaceMethod, annotationType);
                if (annotation != null) {
                    return Optional.of(annotation);
                }
            } catch (NoSuchMethodException ignored) {
                // 接口中没有对应方法
            }
        }
        return Optional.empty();
    }
}